package archer.framework.protocol.result;

import archer.framework.core.ArcherCoreModule;
import archer.framework.protocol.exception.*;
import archer.framework.utils.*;
import jodd.datetime.JDateTime;

import java.math.BigDecimal;
import java.util.*;

/**
 * 执行结果处理类
 *
 * @author Kent
 * @date 2015/7/7.
 */
public class ExecuteResultProcessor {

    //-----------------------------results-------------------------

    /**
     * 执行成功，不带返回结果
     *
     * @return
     */
    public static ExecuteResultWrapper success() {

        // 返回包装类型
        return new ExecuteResultWrapper(new ExecuteResult(ResultCode.SUCCESS));
    }

    /**
     * 执行成功，带返回结果
     *
     * @param data
     * @return
     */
    public static ExecuteResultWrapper success(Object data) {

        // 返回包装类型
        return new ExecuteResultWrapper(new ExecuteResult(ResultCode.SUCCESS).setResultData(data));
    }

    /**
     * 执行结果为true
     *
     * @return
     */
    public static ExecuteResult resultTrue() {

        return new ExecuteResult(ResultCode.TRUE);
    }

    /**
     * 执行结果为false
     *
     * @return
     */
    public static ExecuteResult resultFalse() {

        return new ExecuteResult(ResultCode.FALSE);
    }

    public static ExecuteResult paramNull() {

        return new ExecuteResult(ResultCode.PARAM_NULL);
    }

    public static ExecuteResult paramNull(String msg) {

        return new ExecuteResult(ResultCode.PARAM_NULL, msg);
    }

    public static ExecuteResult paramNull(SmartString msg) {

        return paramNull(msg.toString());
    }

    public static ExecuteResult paramInvalidate() {

        return new ExecuteResult(ResultCode.PARAM_INVALIDATE);
    }

    public static ExecuteResult paramInvalidate(String msg) {

        return new ExecuteResult(ResultCode.PARAM_INVALIDATE, msg);
    }

    public static ExecuteResult paramInvalidate(SmartString msg) {

        return paramInvalidate(msg.toString());
    }

    public static ExecuteResult dataNotExist() {

        return new ExecuteResult(ResultCode.DATA_NOT_EXIST);
    }

    public static ExecuteResult dataNotExist(String msg) {

        return new ExecuteResult(ResultCode.DATA_NOT_EXIST, msg);
    }

    public static ExecuteResult dataNotExist(SmartString msg) {

        return dataNotExist(msg.toString());
    }

    public static ExecuteResult dataDuplicated() {

        return new ExecuteResult(ResultCode.DATA_DUPLICATED);
    }

    public static ExecuteResult dataDuplicated(String msg) {

        return new ExecuteResult(ResultCode.DATA_DUPLICATED, msg);
    }

    public static ExecuteResult dataDuplicated(SmartString msg) {

        return dataDuplicated(msg.toString());
    }

    public static ExecuteResult accessDenied() {

        return new ExecuteResult(ResultCode.ACCESS_DENIED);
    }

    public static ExecuteResult accessDenied(String msg) {

        return new ExecuteResult(ResultCode.ACCESS_DENIED, msg);
    }

    public static ExecuteResult accessDenied(SmartString msg) {

        return accessDenied(msg.toString());
    }

    public static ExecuteResult internalError() {

        return new ExecuteResult(ResultCode.INTERNAL_ERROR);
    }

    public static ExecuteResult internalError(String msg) {

        return new ExecuteResult(ResultCode.INTERNAL_ERROR, msg);
    }

    public static ExecuteResult internalError(SmartString msg) {

        return internalError(msg.toString());
    }

    public static ExecuteResult notLogined() {

        return new ExecuteResult(ResultCode.NOT_LOGINED);
    }

    public static ExecuteResult notLogined(String msg) {

        return new ExecuteResult(ResultCode.NOT_LOGINED, msg);
    }

    public static ExecuteResult notLogined(SmartString msg) {

        return notLogined(msg.toString());
    }

    public static ExecuteResult apitenantAccessDenied() {

        return new ExecuteResult(ResultCode.API_TENANT_ACCESS_DENIED);
    }

    public static ExecuteResult apitenantAccessDenied(String msg) {

        return new ExecuteResult(ResultCode.API_TENANT_ACCESS_DENIED, msg);
    }

    public static ExecuteResult apitenantAccessDenied(SmartString msg) {

        return apitenantAccessDenied(msg.toString());
    }

    public static ExecuteResult noPermission() {

        return new ExecuteResult(ResultCode.NO_PERMISSION);
    }

    public static ExecuteResult noPermission(String msg) {

        return new ExecuteResult(ResultCode.NO_PERMISSION, msg);
    }

    public static ExecuteResult noPermission(SmartString msg) {

        return noPermission(msg.toString());
    }

    public static ExecuteResult conditionNoMet() {

        return new ExecuteResult(ResultCode.CONDITION_NO_MET);
    }

    public static ExecuteResult conditionNoMet(String msg) {

        return new ExecuteResult(ResultCode.CONDITION_NO_MET, msg);
    }

    public static ExecuteResult conditionNoMet(SmartString msg) {

        return conditionNoMet(msg.toString());
    }

    //------------------------------------ exception ----------------------------------------

    public static void throwParamNullException() {

        throw new ParamNullException();
    }

    public static void throwParamNullException(String msg) {

        throw new ParamNullException(msg);
    }

    public static void throwParamInvalidateException() {

        throw new ParamInvalidateException();
    }

    public static void throwParamInvalidateException(String msg) {

        throw new ParamInvalidateException(msg);
    }

    public static void throwDataNotExistException() {

        throw new DataNotExistException();
    }

    public static void throwDataNotExistException(String msg) {

        throw new DataNotExistException(msg);
    }

    public static void throwDataDuplicatedException() {

        throw new DataDuplicatedException();
    }

    public static void throwDataDuplicatedException(String msg) {

        throw new DataDuplicatedException(msg);
    }

    public static void throwAccessDeniedException() {

        throw new AccessDeniedException();
    }

    public static void throwAccessDeniedException(String msg) {

        throw new AccessDeniedException(msg);
    }

    public static void throwInternalErrorException() {

        throw new InternalErrorException();
    }

    public static void throwInternalErrorException(String msg) {

        throw new InternalErrorException(msg);
    }

    public static void throwNotLoginedException() {

        throw new NotLoginedException();
    }

    public static void throwNotLoginedException(String msg) {

        throw new NotLoginedException(msg);
    }

    public static void throwApitenantAccessDeniedException() {

        throw new ApiTenantAccessDeniedException();
    }

    public static void throwApitenantAccessDeniedException(String msg) {

        throw new ApiTenantAccessDeniedException(msg);
    }

    public static void throwNoPermissionException() {

        throw new NoPermissionException();
    }

    public static void throwNoPermissionException(String msg) {

        throw new NoPermissionException(msg);
    }

    public static void throwConditionNoMetException() {

        throw new ConditionNoMetException();
    }

    public static void throwConditionNoMetException(String msg) {

        throw new ConditionNoMetException(msg);
    }

    //-----------------------------utils-------------------------

    /**
     * 空判断
     *
     * @param obj
     * @return
     */
    public static boolean isEmpty(Object obj) {

        return ValidateUtils.isEmpty(obj);
    }

    /**
     * 非空判断
     *
     * @param obj
     * @return
     */
    public static boolean isNotEmpty(Object obj) {

        return ValidateUtils.isNotEmpty(obj);
    }

    /**
     * 非邮箱
     *
     * @param email
     * @return
     */
    public static boolean isNotEmail(String email) {

        return !ValidateUtils.isEmail(email);
    }

    /**
     * 邮箱
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {

        return ValidateUtils.isEmail(email);
    }

    /**
     * 手机号
     *
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile) {

        return ValidateUtils.isMobile(mobile);
    }

    /**
     * 非手机号
     *
     * @param mobile
     * @return
     */
    public static boolean isNotMoblie(String mobile) {

        return !isMobile(mobile);
    }

    /**
     * 字符串转json
     *
     * @param value
     * @param bean
     * @param <T>
     * @return
     */
    public static <T> T deserialize(String value, Class<T> bean) {

        return JSONUtils.deserialize(value, bean);
    }

    /**
     * 数组转map结构
     *
     * @param data
     * @return
     */
    public static Map asMap(Object... data) {

        return MapUtils.asMap(data);
    }

    /**
     * 数组转list结构
     *
     * @param data
     * @return
     */
    public static List asList(Object... data) {

        return Arrays.asList(data);
    }

    /**
     * 构造空集合
     *
     * @return
     */
    public static List emptyList() {

        return new ArrayList();
    }

    /**
     * split string
     *
     * @param s
     * @return
     */
    public static List split(String s) {
        if (isEmpty(s)) {
            return null;
        }

        return asList(s.split(","));
    }

    /**
     * Y
     *
     * @param status
     * @return
     */
    public static boolean isY(String status) {

        return ArcherCoreModule.databaseBooleanTrue.equals(status);
    }

    /**
     * N
     *
     * @param status
     * @return
     */
    public static boolean isN(String status) {

        return ArcherCoreModule.databaseBooleanFalse.equals(status);
    }

    /**
     * SmartString
     *
     * @param template
     * @return
     */
    public static SmartString template(String template) {

        return SmartString.template(template);
    }

    /**
     * ip校验
     *
     * @param address
     * @return
     */
    public static boolean isNetAddress(String address) {

        return ValidateUtils.isNetAddress(address);
    }

    public static boolean isNotNetAddress(String address) {

        return ValidateUtils.isNotNetAddress(address);
    }

    /**
     * ipv4校验
     *
     * @param address
     * @return
     */
    public static boolean isNet4Address(String address) {

        return ValidateUtils.isNetAddress(address);
    }

    public static boolean isNotNet4Address(String address) {

        return ValidateUtils.isNotNet4Address(address);
    }

    public static DateProcessor date(Date date) {

        return DateProcessor.date(date);
    }

    public static DateProcessor date(String date) {
        return DateProcessor.date(date);
    }

    public static DateProcessor date(long millis) {

        return DateProcessor.date(millis);
    }

    public static DateProcessor date(JDateTime date) {

        return DateProcessor.date(date);
    }

    public static DateProcessor today() {

        return DateProcessor.today();
    }

    public static DateProcessor now() {

        return DateProcessor.now();
    }

    public static BigDecimal TWELVE = BigDecimalUtils.TWELVE;

    public static BigDecimal ONE_HUNDRED = BigDecimalUtils.ONE_HUNDRED;

    public static BigDecimal ONE_THOUSAND = BigDecimalUtils.ONE_THOUSAND;

    public static BigDecimal TEN_THOUSAND = BigDecimalUtils.TEN_THOUSAND;

    public static BigDecimal ZERO = BigDecimal.ZERO;

    public static BigDecimal TEN = BigDecimal.TEN;

    public static BigDecimal ONE = BigDecimal.ONE;

    public static BigDecimal add(final BigDecimal start, final BigDecimal... values) {

        return BigDecimalUtils.add(start, values);
    }

    public static BigDecimal subtract(final BigDecimal start, final BigDecimal... values) {

        return BigDecimalUtils.subtract(start, values);
    }

    public static BigDecimal divide(final int numeratorScale, final BigDecimal numerator, final BigDecimal denominator, final int rounding) {

        return BigDecimalUtils.divide(numeratorScale, numerator, denominator, rounding);
    }

    public static BigDecimal multiply(final BigDecimal value, final BigDecimal... multiplicand) {

        return BigDecimalUtils.multiply(value, multiplicand);
    }

    public static BigDecimal bd(final String val) {

        return BigDecimalUtils.bd(val);
    }

    public static <T, E> E sum(List<T> src, Class<E> clazz, String... fields) {

        return Functional.sum(src, clazz, fields);
    }

    public static <T, E> E sum(List<T> src, E target, String... fields) {

        return Functional.sum(src, target, fields);
    }

    public static <T> BigDecimal sum(List<T> src, String field) {

        return Functional.sum(src, field);
    }

    public static <T> List<T> adjustDivideResult(List<T> src, String field, BigDecimal amount) {

        return Functional.adjustDivideResult(src, field, amount);
    }

    public static <T> List<T> adjustDivideResult(List<T> src, Map<String, BigDecimal> amount) {

        return Functional.adjustDivideResult(src, amount);
    }
}
